﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Printing;
using UnityScriptEngine;

namespace MBBHotelReservation
{
    public partial class frmExpenses : Form
    {
        UnityProcessor proc = new UnityProcessor();
        UnityScript[] dat = new UnityScript[0];
        Threader t = new Threader();

        DataTable items = new DataTable();
        string curPO = "";
        string wrnEntMsg = "";
        float gtotal = 0f;

        bool qtyErr = false, prcErr = false,
            cmtErr = false,Committing = false,
            isViewing = false;
        string cat = "";

        //AutoChecker
        Timer tmr = new Timer();
      
        public frmExpenses()
        {
            InitializeComponent();
            InitializeFrameSliderForm();
            
        }
        private void InitializeForm()
        {
            proc.ProcessCompleted += new ProcessHandler(proc_ProcessCompleted);
            proc.ProcessError += new ProcessHandler(proc_ProcessError);
            txtType.SelectedIndex = 0;            
            //Start AutoCheck timer
            txtPrice.TextChanged += new EventHandler(CheckValue);
            btnAdd.Click += new EventHandler(btnAdd_Click);
            btnCommit.Click += new EventHandler(btnCommit_Click);
            btnAdd.LostFocus += new EventHandler(delegate(object sender, EventArgs e)
            {
                txtVoucher.Focus();
            });
            
            mnuRemoveEntry.Click += new EventHandler(mnuRemoveEntry_Click);
            t.MethodCompleted += new EventHandler(t_MethodCompleted);
            btnCommit.Visible = false;
            btnAdd.Visible = false;
            
            InitializeItemTable();
            txtDescription.Focus();
            txtCategory.SelectedIndex = 0;
        }

        void btnPrint_Click(object sender, EventArgs e)
        {
            PrintPO();
        }
        void mnuRemoveEntry_Click(object sender, EventArgs e)
        {
            if (grdItems.SelectedRows.Count == 0) return;
            DialogResult dlg = MessageBox.Show("The entry will be permanently deleted from the list.\r\n" +
                "Do you wish to continue?", "Commit", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
            if (dlg == System.Windows.Forms.DialogResult.No) return;
            int sel = grdItems.SelectedRows[0].Index;
            items.Rows[sel].Delete();
            t.MethodCall(CheckEntry);
        }
        void btnCommit_Click(object sender, EventArgs e)
        {
            DialogResult dlg = MessageBox.Show("Please double check your entries before committing.\r\n" +
                "Do you wish to continue saving?", "Commit", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (dlg == System.Windows.Forms.DialogResult.No) return;
                
            Committing = true;
            States(false);
            cat = txtCategory.Text;
            t.MethodCall(CommitExpenses);
        }
        void btnAdd_Click(object sender, EventArgs e)
        {
            if (txtDescription.Text != "")
            {
                DataRow dr = items.NewRow();
                dr["Voucher"] = txtVoucher.Text;
                dr["Description"] = txtDescription.Text;
                dr["Amount"] = float.Parse(txtPrice.Text);
                dr["Type"] = txtType.Text;
                dr["Category"] = txtCategory.Text;

                items.Rows.Add(dr);
                txtVoucher.Text = "";
                txtPrice.Text = "";
                txtDescription.Text = "";
                txtType.SelectedIndex = 0;

                t.MethodCall(CheckEntry);
            }
        }
        void CheckValue(object sender, EventArgs e)
        {
            t.MethodCall(CheckEntry);
        }
        //Process Ended
        void proc_ProcessError(string id, string desc)
        {
            t.SafeCall(this, delegate
            {
                
                MessageBox.Show(desc);
                States(true);
                switch (id)
                {
                    case "COMMIT":
                        Committing = false;
                        break;
                }
                tmr.Enabled = true;
            });
        }
        void proc_ProcessCompleted(string id, string desc)
        {
            t.SafeCall(this, delegate
            {
                switch (id)
                {
                    case "INITGEN":
                        cat = txtCategory.Text;
                        t.MethodCall(LoadData);
                        break;
                    case "GENERATE":
                    case "INIT":
                        break;
                    case "COMMIT":
                        btnClose_Click(null, null);
                        break;
                    case "LOAD":
                        proc.DBPUX_Data_Fetch(out dat);
                        lblWarningEntry.Text = "Loaded @ " + proc.ProcEnd() + " sec.";
                        break;
                };
                if (Committing || isViewing) return;
                tmr.Enabled = true;
                States(true);
            });
        }
        void t_MethodCompleted(object sender, EventArgs e)
        {
            t.SafeCall(this, delegate
            {
                switch(sender.ToString())
                {
                    case "CheckEntry":
                        lblWarningEntry.Text = wrnEntMsg;

                        if (prcErr)
                            txtPrice.ForeColor = Color.Red;
                        else
                            txtPrice.ForeColor = Color.Black;

                        if (!prcErr)
                            btnAdd.Visible = true;
                        else
                            btnAdd.Visible = false;

                        txtTotal.Text = gtotal.ToString("#,#0.00");
                        btnCommit.Visible = !cmtErr;
                        break;
                    case "CheckContent":
                        btnCommit.Visible = !cmtErr;
                        break;
                }
                if (Committing) return;
                tmr.Enabled = true;
            });
        }

        //Operations
        void LoadData()
        {
            while (proc.IsRunning)
            {
                System.Threading.Thread.Sleep(1);
            }
            proc.ProcStart();
            UnityScript x = new UnityScript("LOAD", 4);
            x.Script_Add(Script.DBPUX_BEGIN);
            x.Script_Add(Script.DBPUX_QUERY, string.Format("SELECT fCategory AS 'Category', fDescription AS 'Description', fType AS 'Type', fAmount AS 'Amount' FROM tblExpenses WHERE fDate='{0}' ",curPO));
            x.Script_Add(Script.DBPUX_COMMIT);
            proc.Run(x);
        }
        void InitializeItemTable()
        {
            items.Columns.Add("Voucher");
            items.Columns.Add("Description");
            items.Columns.Add("Amount");
            items.Columns.Add("Type");
            items.Columns.Add("Category");

            items.Columns[2].DataType = typeof(float);
            items.Columns[2].DefaultValue = 0.00f;

            grdItems.DataSource = items;

            grdItems.Columns[1].DefaultCellStyle.WrapMode = DataGridViewTriState.True;

            grdItems.Columns[2].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            grdItems.Columns[3].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;
            grdItems.Columns[2].DefaultCellStyle.Format = "#,#0.00";

            grdItems.Columns[0].Width = (grdItems.Width * 10) / 100;
            grdItems.Columns[1].Width = (grdItems.Width * 50) / 100;
        }
        void CheckEntry()
        {
            float fprice = 0f;
            string price = txtPrice.Text;
            //Check if Commit is valid
            if (items.Rows.Count != 0)
            {
                cmtErr = false;
            }
            else 
            {
                cmtErr = true;
            }
            //Check Price
            if (!float.TryParse(price, out fprice))
            {
                prcErr = true;
                wrnEntMsg = "";
                wrnEntMsg += "Invalid AMOUNT value detected!\r\n";
            }
            else
            {
                prcErr = false;
                if(!qtyErr) wrnEntMsg = "";
            }
            //Compute for the total
            gtotal = 0;
            for (int i = 0; i < items.Rows.Count; i++)
            {
                gtotal += (float)items.Rows[i]["Amount"];
            }
        }
        void CommitExpenses()
        {
            UnityScript u = new UnityScript("COMMIT", 5);
            u.Script_Add(Script.DBPUX_BEGIN);
            //Construct Expenses Items
            for (int i = 0; i < items.Rows.Count; i++)
            {
                u.Script_Add(Script.DBPUX_INSERT, "tblExpenses(fVoucher, fDescription, fDate, fAmount, fType, fCategory)",
                    new string[]{
                        items.Rows[i]["Voucher"].ToString(),
                        items.Rows[i]["Description"].ToString(),
                        txtDate.Value.ToString("yyyy-MM-dd"),
                        items.Rows[i]["Amount"].ToString(),
                        items.Rows[i]["Type"].ToString(),
                        items.Rows[i]["Category"].ToString()
                    });
            }
            //Transaction Log
            //u.Script_Add(Script.DBPUX_INSERT, "tblpurchaseorderlog(fUser, fMsg, fDate)",
            //    new string[]{
                    //StoreClientModule.Common.Username,
            //        "Added " + txtPONum.Text + " worth " + gtotal.ToString("#,#0.00"),
            //        DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
           //     });
            u.Script_Add(Script.DBPUX_COMMIT);
            //Wait if UnityCall is in progress.
            System.Threading.Thread.Sleep(10);
            while (proc.IsRunning)
            {

            }
            proc.Run(u);
        }
          
        void States(bool s)
        {
            grpDetails.Enabled = s;
            grdItems.Enabled = s;
        }

        //Printing Module
        void PrintPO()
        {
            PrintDocument pd = new PrintDocument();
            pd.DocumentName = lblText.Text;
            pd.PrintPage += new PrintPageEventHandler(pd_PrintPage);
            PrintDialog pdlg = new PrintDialog();
            pdlg.Document = pd;
            if (pdlg.ShowDialog() == DialogResult.OK)
            {
                PrintPreviewDialog ppdlg = new PrintPreviewDialog();
                ppdlg.Document = pd;
                ppdlg.ShowDialog();
            }
        }
        void pd_PrintPage(object sender, PrintPageEventArgs e)
        {
            float lpp = 0;
            float y = 0;
            float tm = e.MarginBounds.Top;
            float lm = e.PageBounds.Left + 50;
            float lw = e.PageBounds.Width - 50;
            float th = e.PageBounds.Height - 100;
            float tHt = 0;
            Font cFont;
            StringFormat sf = new StringFormat();
            //Title
            cFont = new Font("Arial", 16f, FontStyle.Bold);
            tHt = cFont.GetHeight(e.Graphics);
            y = 50;
            sf.Alignment = StringAlignment.Center;
            e.Graphics.DrawString("MBB ROYALE INT'L INC.", cFont, Brushes.Black, (lw + 100) / 2, y, sf);
            //SubTitle
            y += tHt;
            cFont = new Font("Arial", 8f, FontStyle.Regular);
            tHt = cFont.GetHeight(e.Graphics);
            e.Graphics.DrawString("MacArthur Hi-way, Guinhawa, Malolos Bulacan", cFont, Brushes.Black, (lw + 100) / 2, y, sf);
            //SubTitle
            y += tHt;
            cFont = new Font("Arial", 8f, FontStyle.Regular);
            tHt = cFont.GetHeight(e.Graphics);
            e.Graphics.DrawString("Telephone Number: (044) 791-03-78 , (044) 662-40-79", cFont, Brushes.Black, (lw + 100) / 2, y, sf);
            //SubTitle
            y += tHt;
            cFont = new Font("Arial", 8f, FontStyle.Regular);
            tHt = cFont.GetHeight(e.Graphics);
            //e.Graphics.DrawString("Fax Number: (044) 662-37-62", cFont, Brushes.Black, (lw + 100) / 2, y, sf);
            //Line
            y += tHt;
            y += tHt;
            cFont = new Font("Arial", 12f, FontStyle.Bold);
            e.Graphics.DrawString("PURCHASE ORDER FORM", cFont, Brushes.Black, (lw + 100) / 2, y, sf);
            y += tHt;
            y += tHt;
            y += tHt;
            e.Graphics.DrawLine(new Pen(Color.Black), new PointF(lm, y), new PointF(lw, y));
            //SUPPLIER Line
            y += tHt;
            y += tHt;
            cFont = new Font("Arial", 12f, FontStyle.Bold);
            tHt = cFont.GetHeight(e.Graphics);
            e.Graphics.DrawString("REFERENCE NO: ", cFont, Brushes.Black, lm + 20, y, new StringFormat());
            e.Graphics.DrawString("P.O. NO: ", cFont, Brushes.Black, lw - 280, y, new StringFormat());

            cFont = new Font("Arial", 12f, FontStyle.Italic);
    //        e.Graphics.DrawString("" + txtRefNum.Text, cFont, Brushes.Black, lm + 180, y, new StringFormat());
    //        e.Graphics.DrawString("" + txtPONum.Text, cFont, Brushes.Black, 600, y, new StringFormat());

            y += tHt;
            e.Graphics.DrawLine(new Pen(Color.Black), new PointF(lm + 180, y), new PointF(500, y));
            e.Graphics.DrawLine(new Pen(Color.Black), new PointF(760, y), new PointF(600, y));
            //SUPPLIER Line
            cFont = new Font("Arial", 12f, FontStyle.Bold);
            tHt = cFont.GetHeight(e.Graphics);
            e.Graphics.DrawString("SUPPLIER NAME: ", cFont, Brushes.Black, lm + 20, y, new StringFormat());
            e.Graphics.DrawString("DATE: ", cFont, Brushes.Black, lw - 280, y, new StringFormat());

            cFont = new Font("Arial", 12f, FontStyle.Italic);
      //      e.Graphics.DrawString("" + txtSupplierName.Text, cFont, Brushes.Black, lm + 180, y, new StringFormat());
            e.Graphics.DrawString("" + txtDate.Text, cFont, Brushes.Black, 600, y, new StringFormat());

            y += tHt;
            e.Graphics.DrawLine(new Pen(Color.Black), new PointF(lm + 180, y), new PointF(500, y));
            e.Graphics.DrawLine(new Pen(Color.Black), new PointF(760, y), new PointF(600, y));
            //ADDRESS Line

            cFont = new Font("Arial", 12f, FontStyle.Bold);
            tHt = cFont.GetHeight(e.Graphics);
            e.Graphics.DrawString("ADDRESS: ", cFont, Brushes.Black, lm + 20, y, new StringFormat());
            cFont = new Font("Arial", 12f, FontStyle.Italic);
            e.Graphics.DrawString("" + txtDescription.Text, cFont, Brushes.Black, lm + 180, y, new StringFormat());

            y += tHt;
            e.Graphics.DrawLine(new Pen(Color.Black), new PointF(lm + 180, y), new PointF(760, y));

            y += tHt;
            //Table Columns
            cFont = new Font("Arial", 11f, FontStyle.Bold);
            y += tHt;
            e.Graphics.DrawString("No.", cFont, Brushes.Black, lm + 4, y, new StringFormat());
            e.Graphics.DrawString("Description", cFont, Brushes.Black, lm + 40, y, new StringFormat());
            e.Graphics.DrawString("Qty", cFont, Brushes.Black, lm + 405, y, new StringFormat());
            e.Graphics.DrawString("Price", cFont, Brushes.Black, lm + 565, y, new StringFormat());
            e.Graphics.DrawString("Sub Total", cFont, Brushes.Black, lm + 660, y, new StringFormat());

            e.Graphics.DrawLine(new Pen(Color.Black), new PointF(lm, y - (tHt / 2)), new PointF(lw, y - (tHt / 2)));
            e.Graphics.DrawLine(new Pen(Color.Black), new PointF(lm, y + tHt), new PointF(lw, y + tHt));
            e.Graphics.DrawLine(new Pen(Color.Black), new PointF(lm, y - (tHt / 2)), new PointF(lm, y + tHt));
            e.Graphics.DrawLine(new Pen(Color.Black), new PointF(lw, y - (tHt / 2)), new PointF(lw, y + tHt));

            e.Graphics.DrawLine(new Pen(Color.Black), new PointF(lm + 35, y - (tHt / 2)), new PointF(lm + 35, y + tHt));
            e.Graphics.DrawLine(new Pen(Color.Black), new PointF(lm + 400, y - (tHt / 2)), new PointF(lm + 400, y + tHt));
            e.Graphics.DrawLine(new Pen(Color.Black), new PointF(lm + 560, y - (tHt / 2)), new PointF(lm + 560, y + tHt));
            e.Graphics.DrawLine(new Pen(Color.Black), new PointF(lm + 655, y - (tHt / 2)), new PointF(lm + 655, y + tHt));

            //Table
            y += (tHt * 1.25f);
            cFont = new Font("Arial Narrow", 10f, FontStyle.Regular);
            tHt = cFont.GetHeight(e.Graphics);
            bool nf = false;
            for (int i = 0; i < 30; i++)
            {
                e.Graphics.DrawString((i + 1) + "", cFont, Brushes.Black, lm + 4, y, new StringFormat());
                if (grdItems.Rows.Count > i)
                {
                    e.Graphics.DrawString("" + grdItems.Rows[i].Cells[1].Value.ToString(), cFont, Brushes.Black, lm + 40, y, new StringFormat());
                    e.Graphics.DrawString("" + grdItems.Rows[i].Cells[2].Value.ToString(), cFont, Brushes.Black, lm + 405, y, new StringFormat());
                    e.Graphics.DrawString("" + grdItems.Rows[i].Cells[3].Value.ToString(), cFont, Brushes.Black, lm + 565, y, new StringFormat());
                    e.Graphics.DrawString("" + grdItems.Rows[i].Cells[4].Value.ToString(), cFont, Brushes.Black, lm + 660, y, new StringFormat());
                }
                else
                {
                    if (!nf)
                    {
                        //Nothing Follows
                        e.Graphics.DrawString("******************** Nothing Follows ********************", cFont, Brushes.Black, lm + 300, y, new StringFormat());
                        nf = true;
                    }
                }
                e.Graphics.DrawLine(new Pen(Color.Black), new PointF(lm, y + tHt), new PointF(lw, y + tHt));
                e.Graphics.DrawLine(new Pen(Color.Black), new PointF(lm, y - (tHt / 2)), new PointF(lm, y + tHt));
                e.Graphics.DrawLine(new Pen(Color.Black), new PointF(lw, y - (tHt / 2)), new PointF(lw, y + tHt));

                e.Graphics.DrawLine(new Pen(Color.Black), new PointF(lm + 35, y - (tHt / 2)), new PointF(lm + 35, y + tHt));
                e.Graphics.DrawLine(new Pen(Color.Black), new PointF(lm + 400, y - (tHt / 2)), new PointF(lm + 400, y + tHt));
                e.Graphics.DrawLine(new Pen(Color.Black), new PointF(lm + 560, y - (tHt / 2)), new PointF(lm + 560, y + tHt));
                e.Graphics.DrawLine(new Pen(Color.Black), new PointF(lm + 655, y - (tHt / 2)), new PointF(lm + 655, y + tHt));

                y += (tHt * 1.25f);

            }

            //STORE Line
            y += tHt;
            cFont = new Font("Arial", 12f, FontStyle.Bold);
            tHt = cFont.GetHeight(e.Graphics);
            e.Graphics.DrawString("NUMBER OF ITEMS: " + grdItems.Rows.Count, cFont, Brushes.Black, lm + 20, y, new StringFormat());
            y += tHt;
            cFont = new Font("Arial", 12f, FontStyle.Bold);
            tHt = cFont.GetHeight(e.Graphics);
            e.Graphics.DrawString("SHIP TO: ", cFont, Brushes.Black, lm + 20, y, new StringFormat());
            cFont = new Font("Arial", 11f, FontStyle.Italic);
            //e.Graphics.DrawString("" + StoreClientModule.Common.lStoreName, cFont, Brushes.Black, lm + 180, y, new StringFormat());
            y += tHt;
            e.Graphics.DrawLine(new Pen(Color.Black), new PointF(lm + 180, y), new PointF(500, y));
            cFont = new Font("Arial", 12f, FontStyle.Bold);
            e.Graphics.DrawString("ADDRESS: ", cFont, Brushes.Black, lm + 20, y, new StringFormat());
            cFont = new Font("Arial", 11f, FontStyle.Italic);
           // e.Graphics.DrawString("" + StoreClientModule.Common.lStoreAddress, cFont, Brushes.Black, lm + 180, y, new StringFormat());
            y += tHt;
            e.Graphics.DrawLine(new Pen(Color.Black), new PointF(lm + 180, y), new PointF(760, y));

            y += tHt;
            e.Graphics.DrawString("_____________________________", cFont, Brushes.Black, lw - 190, y, sf);

            y += tHt;
            cFont = new Font("Arial", 12f, FontStyle.Bold);
            tHt = cFont.GetHeight(e.Graphics);
            e.Graphics.DrawString("AUTHORIZED SIGNATURE", cFont, Brushes.Black, lw - 190, y, sf);

        }
    }
    //Code Log:
    //- Speed up entry checking by removing the method call from the timer.
    //- Removed the CheckContent method as the CheckEntry method is sufficient for checking
    //  user inputs.
}